package com.ym521.facecheck.core

import android.graphics.Bitmap
import org.opencv.android.Utils
import org.opencv.core.Mat
import org.opencv.core.Point
import org.opencv.core.Rect
import org.opencv.core.Scalar
import org.opencv.imgproc.Imgproc
import kotlin.math.roundToInt

/**
 *@author Ym
 *E-mail: 2435970206@qq.com
 *createTime:2024/6/22
 *explain:
 *
 */
internal class ImageFaceVisualizeEngine private constructor() : IImageFaceVisualizeEngine {
    private lateinit var BOX_COLOR: Scalar
    private lateinit var RIGHT_EYE_COLOR: Scalar
    private lateinit var LEFT_EYE_COLOR: Scalar
    private lateinit var NOSE_TIP_COLOR: Scalar
    private lateinit var MOUTH_RIGHT_COLOR: Scalar
    private lateinit var MOUTH_LEFT_COLOR: Scalar

     companion object{
         fun build():IImageFaceVisualizeEngine{
             return ImageFaceVisualizeEngine()
         }
     }

    override fun initEngine(): IImageFaceVisualizeEngine {
        BOX_COLOR = Scalar(0.0, 255.0, 0.0)
        RIGHT_EYE_COLOR = Scalar(255.0, 0.0, 0.0)
        LEFT_EYE_COLOR = Scalar(0.0, 0.0, 255.0)
        NOSE_TIP_COLOR = Scalar(0.0, 255.0, 0.0)
        MOUTH_RIGHT_COLOR = Scalar(255.0, 0.0, 255.0)
        MOUTH_LEFT_COLOR = Scalar(0.0, 255.0, 255.0)
        return this
    }

    override fun visualizeFace(rgba: Mat, faces: Mat): Bitmap {
        val thickness = 2
        val faceData = FloatArray(faces.cols() * faces.channels())
        for (i in 0 until faces.rows()) {
            faces[i, 0, faceData]
            // Draw bounding box
            Imgproc.rectangle(
                rgba, Rect(
                    faceData[0].roundToInt(), Math.round(faceData[1]),
                    faceData[2].roundToInt(), Math.round(faceData[3])
                ),
               BOX_COLOR, thickness
            )
            // Draw landmarks
            Imgproc.circle(
                rgba,
                Point(
                    faceData[4].roundToInt().toDouble(),
                    faceData[5].roundToInt().toDouble()
                ),
                2,
               RIGHT_EYE_COLOR,
                thickness
            )
            Imgproc.circle(
                rgba,
                Point(
                    faceData[6].roundToInt().toDouble(),
                    faceData[7].roundToInt().toDouble()
                ),
                2,
               LEFT_EYE_COLOR,
                thickness
            )
            Imgproc.circle(
                rgba,
                Point(
                    faceData[8].roundToInt().toDouble(),
                    faceData[9].roundToInt().toDouble()
                ),
                2,
               NOSE_TIP_COLOR,
                thickness
            )
            Imgproc.circle(
                rgba,
                Point(
                    faceData[10].roundToInt().toDouble(),
                    faceData[11].roundToInt().toDouble()
                ),
                2,
               MOUTH_RIGHT_COLOR,
                thickness
            )
            Imgproc.circle(
                rgba,
                Point(
                    faceData[12].roundToInt().toDouble(),
                    faceData[13].roundToInt().toDouble()
                ),
                2,
               MOUTH_LEFT_COLOR,
                thickness
            )
        }
        val resultBitmap = Bitmap.createBitmap(rgba.cols(), rgba.rows(), Bitmap.Config.RGB_565)
        Utils.matToBitmap(rgba, resultBitmap)
        return resultBitmap
    }
}